unit uLoadExcelThread;

interface

uses
  System.Classes, System.SysUtils, System.Variants, System.Win.ComObj,
  Vcl.ComCtrls, Vcl.StdCtrls, Vcl.ExtCtrls, uBaseCompThread, Vcl.Dialogs,
  System.UITypes;

type
//  TLoadExcelProcess = class(TThread)
  TLoadExcelProcess = class(TBaseCompThread)
  private
    { Private declarations }
    FilePaths: TStrings;
    ErrorMessage: string;

    function VarToCurr(Value: Variant): Currency;
    procedure ErrorDialog;
  protected
    procedure Execute; override;
  public
    constructor Create(CreateSuspended: Boolean; FilePaths: TStrings;
                       ProgressBar: TProgressBar; StatusBar: TStatusBar;
                       PageControl: TPageControl; LoadExcelFileBtn,
                       UpdateBtn: TButton; InsPanel: TPanel); overload;
  end;

var
  LoadExcelProcess: TLoadExcelProcess;

implementation

uses uCompDM;

// TLoadExcelProcess
// Поток для парсинга файла Excel

constructor TLoadExcelProcess.Create(CreateSuspended: Boolean; FilePaths: TStrings;
                                     ProgressBar: TProgressBar; StatusBar: TStatusBar;
                                     PageControl: TPageControl; LoadExcelFileBtn,
                                     UpdateBtn: TButton; InsPanel: TPanel);
begin
  inherited Create(CreateSuspended, ProgressBar, StatusBar, PageControl,
                   LoadExcelFileBtn, UpdateBtn, InsPanel);

  Self.FilePaths := FilePaths;
end;

function TLoadExcelProcess.VarToCurr(Value: Variant): Currency;
begin
  // Преобразование Variant в Currency с изменением разделителя
  Result := StrToCurr(CompDM.UpdateDecimalSeparator(VarToStr(Value)));
end;

procedure TLoadExcelProcess.ErrorDialog;
begin
  MessageDlg(ErrorMessage, mtError, [mbOK], 0);
end;

procedure TLoadExcelProcess.Execute;
var ExcelApp, WorkSheet, FData: OLEVariant;
    i, Rows, StartIndex: Integer;
    PredprId: Int64;
    PredprName, FileName, ShortName: string;
    dopunn: Variant;
begin
  // Создание объекта для работы с XLS/XLSX
  ExcelApp := CreateOleObject('Excel.Application');

  with CompDM do
  try
    Self.Enabled := False;
    Synchronize(ChangeControlAvailability);

    Self.PBStyle := pbstMarquee;
    Synchronize(SetProgressBarStyle);

    CrExcelTemp.ExecSQL;

    for FileName in Self.FilePaths do
    begin
      StartIndex := 3;
      ShortName :=  Copy(FileName, LastDelimiter('\', FileName)+1,
                         Length(FileName)-LastDelimiter('\', FileName));

      Self.StatusText := 'Загрузка файла '+ShortName;
      Synchronize(SetStatusBarText);

      ExcelApp.Workbooks.Open(FileName);

      WorkSheet:= ExcelApp.Workbooks[1].WorkSheets[1];
      Rows:=WorkSheet.UsedRange.Rows.Count;
      FData:=WorkSheet.UsedRange.Value;

      Self.StatusText := 'Вставка записей '+ShortName+' в таблицу...';
      Synchronize(SetStatusBarText);

      // Поиск номера первой строки с информацией
      for I := 1 to Rows do
        if (Length(Trim(VarToStr(FData[I, 1])))<>0) and (Trim(VarToStr(FData[I, 1]))<>'Код страны поставщика') then
        begin
          StartIndex := I;
          Break;
        end;

      // Цикл считывания информации из файла и вставка во временную таблицу
      for I := StartIndex to Rows do
      begin
        if Length(Trim(VarToStr(FData[I, 3])))=0 then
        begin
          PredprId := StrToInt64(Trim(VarToStr(FData[I, 2]))+'0000');
          PredprName := Trim(VarToStr(FData[I, 2]))+' - '+Trim(VarToStr(FData[I, 4]));
        end
        else
        begin
          PredprId := StrToInt64(Trim(VarToStr(FData[I, 2]))+
                                 Trim(VarToStr(FData[I, 3])));
          PredprName := Trim(VarToStr(FData[I, 2]))+' '+Trim(VarToStr(FData[I, 3]))+
                        ' - '+Trim(VarToStr(FData[I, 4]));
        end;

        if Length(Trim(VarToStr(FData[I, 10]))) = 0 then
          dopunn := null
        else
          dopunn := Trim(VarToStr(FData[I, 10]));

        try
          InsertExcelTemp(PredprId, PredprName, VarToStr(FData[I, 15]),
                          VarToStr(FData[I, 38]), 'П',  VarToStr(FData[I, 11]),
                          VarToStr(FData[I, 14]), VarToDateTime(FData[I, 20]),
                          VarToDateTime(FData[I, 39]), 5, VarToCurr(FData[I, 43]),
                          VarToCurr(FData[I, 41]), VarToCurr(FData[I, 44]),
                          dopunn);
        except
          on eIns: EInsExcelTempException do
          begin
            Self.ErrorMessage := eIns.Message;
            Synchronize(ErrorDialog);
          end;
          on eConv: EVariantTypeCastError do
          begin
            Self.ErrorMessage := 'Ошибка преобразования в строку в ЭСЧФ '+VarToStr(FData[I, 15]);
            Synchronize(ErrorDialog);
          end;
        end;
      end;

      ExcelApp.Workbooks.Close;
    end;
  finally
    Self.StatusText := 'Выгрузка файла камерального контроля...';
    Synchronize(SetStatusBarText);

    ExcelApp.Quit;
    VarClear(FData);
    VarClear(WorkSheet);
    VarClear(ExcelApp);
  end;

  Self.StatusText := 'Обработка завершена';
  Synchronize(SetStatusBarText);

  Self.Enabled := True;
  Synchronize(ChangeControlAvailability);

  Self.PBStyle := pbstNormal;
  Synchronize(SetProgressBarStyle);
end;

end.
